package com.list88zhu.android.compiler;

import com.google.auto.service.AutoService;
import com.list88zhu.android.annotation.Subscribe;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;

import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;

/**
 * @author dell
 */

@AutoService(Processor.class)
public class EventBusAnnotationProcessor extends AbstractProcessor {

    private Filer filer;
    private Messager messager;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        filer = processingEnvironment.getFiler();
        messager = processingEnvironment.getMessager();
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        messager.printMessage(Diagnostic.Kind.WARNING, "----------------------------");
        for (TypeElement typeElement : set) {
            Set<? extends Element> annotationSet = roundEnvironment.getElementsAnnotatedWith(typeElement);
            for (Element element : annotationSet) {
                Subscribe subscribe = element.getAnnotation(Subscribe.class);
                int priority = subscribe.priority();
                boolean sticky = subscribe.sticky();
                createFile(priority, sticky);
            }
        }
        return true;
    }

    private void createFile(int age, boolean sticky) {
        try {
            MethodSpec dealHelloWorldMethod = MethodSpec.methodBuilder("parseHelloWorld")
                .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                .returns(void.class)
                .addStatement("$T.out.println($S)", System.class, " is " + sticky)
                .build();

            MethodSpec dealHelloWorldAge = MethodSpec.methodBuilder("dealHelloWorldAge")
                .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                .returns(int.class)
                .addStatement("return " + age)
                .build();

            TypeSpec helloWorldClass = TypeSpec.classBuilder("MyEventBusIndex")
                .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                .addMethod(dealHelloWorldMethod)
                .addMethod(dealHelloWorldAge)
                .build();

            JavaFile helloWorldJava = JavaFile.builder("com.list88zhu.android.compiler", helloWorldClass)
                .build();

            helloWorldJava.writeTo(filer);
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> set = new LinkedHashSet<>();
        set.add(Subscribe.class.getCanonicalName());
        return set;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }
}
